/**
    @file ctc_asw_acl.h

    @author  Copyright (C) 2011 Centec Networks Inc.  All rights reserved.

    @date 2016-01-19

	@version v0.0
    This module provides access to the Access control list features. ACL
    can be used to classify packets based on predefined protocol fields from Layer 2
    through Layer 4.
\b
    Based on these classifications, various actions can be taken, such as:
\p
\d        Discarding the packet
\d        Sending the packet to the CPU
\d        Sending the packet to a mirror port
\d        Sending the packet on a different CoS queue
\d        Changing the ToS, VLAN or other fields
\b

    There are 9 lookup type for TCAM. User must set the acl lookup key
    type in gport, vlan profile or l3 interface profile.
\p
    CAM: mac, mac-ext, ipv4, mac-ipv4, ipv4-EXT, mac-ipv6, ipv6, ipv6-ext, udf.
\b
\p
\t   |          Key Type             |   Description                                                    |
\t   |-------------------------------|------------------------------------------------------------------|
\t   |    CTC_ACL_KEY_MAC            |   Key160_mac_view0, Support L2 Header of the Packet              |
\t   |    CTC_ACL_KEY_MAC_EXT        |   Key160_macudf_view0, Support L2 Header of the Packet with Udf  |
\t   |    CTC_ACL_KEY_IPV4           |   Key160_ip_view0, Support L3 Header of the IPv4 Packet          |
\t   |    CTC_ACL_KEY_MAC_IPV4       |   key320_macipudf_view0, Support L2/L3/L4 Header of IPv4 Packet  |
\t   |    CTC_ACL_KEY_IPV4_EXT       |   Key320_ipudf_view0, Support L3 Header of the packet with Udf   |
\t   |    CTC_ACL_KEY_MAC_IPV6       |   key640_macipv6_view0, Support L2/L3/L4 Header of IPv6 packet   |
\t   |    CTC_ACL_KEY_IPV6           |   key320_ipv6_view0, Support L3 Header of IPv6 packet            |
\t   |    CTC_ACL_KEY_IPV6_EXT       |   Key640_macipv6udf_view0,Support L2/L3/L4 Header of IPv6 packet |
\t   |    CTC_ACL_KEY_UDF            |   Key160_ethudf_view0, Support Udf of packet                     |
\t   |-------------------------------|------------------------------------------------------------------|
\p
\b
    Here are the details of keys:
\p
\d  Key160_mac_view0:
    Field: ETHER_TYPE, MAC_DA, MAC_SA, SVLAN_ID, SCOS, SCFI, SVLAN_VALID, PKT_LEN_RANGE,
           L4_SRC_PORT_RANGE, L4_DST_PORT_RANGE;
\b
\d  Key160_macudf_view0:
    Field: ETHER_TYPE, MAC_DA, MAC_SA, SVLAN_ID, SCOS, SCFI, SVLAN_VALID, PKT_LEN_RANGE,
           L4_SRC_PORT_RANGE, L4_DST_PORT_RANGE, UDF;
    Note: MAC_DA, MAC_SA Only can support one on the same time.
\b
\d  Key160_ip_view0:
    Fixed fields: IP_PROTOCOL, L3_TYPE, FRAG_INFO, IPV4_DA, IPV4_SA, IP_OPTIONS,
                  L4_TYPE, L4_DST_PORT, L4_SRC_PORT, PKT_LEN_RANGE, L4_SRC_PORT_RANGE, L4_DST_PORT_RANGE;
\b
\d  key320_macipudf_view0:
    Field: MAC_DA, MAC_SA, SVLAN_ID, SVLAN_VALID, IP_PROTOCOL, L3_TYPE, FRAG_INFO, IPV4_DA, IPV4_SA, IP_OPTIONS,
           L4_TYPE, L4_SRC_PORT, L4_DST_PORT, PKT_LEN_RANGE, L4_SRC_PORT_RANGE, L4_DST_PORT_RANGE, UDF;
\b
\d  Key320_ipudf_view0:
    Fields: ETHER_TYPE, SVLAN_ID, SVLAN_VALID, PKT_LEN_RANGE, IP_PROTOCOL, L3_TYPE, FRAG_INFO, IPV4_DA, IPV4_SA,
           IP_OPTIONS, L4_TYPE, L4_SRC_PORT, L4_DST_PORT, PKT_LEN_RANGE, L4_SRC_PORT_RANGE, L4_DST_PORT_RANGE, UDF;
\b
\d  key640_macipv6_view0:
    Fields: ETHER_TYPE, MAC_DA, MAC_SA, SVLAN_ID, STAG_COS, STAG_CFI, STAG_VALID, CVLAN_ID, CTAG_COS, CTAG_CFI,
            CTAG_VALID, IP_PROTOCOL, L3_TYPE, FRAG_INFO, IPV6_DA, IPV6_SA, IP_OPTIONS, L4_TYPE,
            PKT_LEN_RANGE,L4_SRC_PORT_RANGE, L4_DST_PORT_RANGE;
\b
\d  key320_ipv6_view0:
    Fields: IP_PROTOCOL, L3_TYPE, FRAG_INFO, IPV6_DA, IPV6_SA, IP_OPTIONS,
            L4_TYPE, PKT_LEN_RANGE,L4_SRC_PORT_RANGE, L4_DST_PORT_RANGE;
\b
\d  Key640_macipv6udf_view0:
    Fields: ETHER_TYPE, MAC_DA, MAC_SA, SVLAN_ID, STAG_COS, STAG_CFI, STAG_VALID, CVLAN_ID, CTAG_COS, CTAG_CFI,
            CTAG_VALID, IP_PROTOCOL, L3_TYPE, FRAG_INFO, IPV6_DA, IPV6_SA, IP_OPTIONS, L4_TYPE,
            PKT_LEN_RANGE,L4_SRC_PORT_RANGE, L4_DST_PORT_RANGE, UDF;
\b
\d  Key160_ethudf_view0:
    Fields: L3_TYPE, L4_TYPE, PKT_LEN_RANGE, L4_SRC_PORT_RANGE, L4_DST_PORT_RANGE, UDF;
    Entry-id:        This represents a acl entry, and is a global concept. In other words,
                     the entry-id is unique for all acl groups.In TMA, the entry id is HW Index.
\b
The module provides APIs to support ACL:
\p
\d Add acl entry by ctcs_acl_add_entry()
\d Remove acl entry by ctcs_acl_remove_entry()
\d Install acl entry to hardware by ctcs_acl_install_entry()
\d Remove acl entry from hardware by ctcs_acl_uninstall_entry()
\d Add key field by ctcs_acl_add_key_field_list()
\d Add action field by ctcs_acl_add_action_field_list()
\d Remove action field by ctcs_acl_remove_action_field_list()
\d Add udf entry by ctcs_acl_add_udf_entry()
\d Remove udf entry by ctcs_acl_remove_udf_entry()
\d Add range info by ctcs_acl_add_range_info()
\d Remove range info by ctcs_acl_remove_range_info()

\S ctc_acl.h:ctc_acl_key_type_t
\S ctc_acl.h:ctc_acl_vlan_edit_t
\S ctc_acl.h:ctc_acl_entry_t
\S ctc_acl.h:ctc_acl_global_cfg_t
\S ctc_acl.h:ctc_field_key_type_t
\S ctc_acl.h:ctc_field_port_t
\S ctc_acl.h:ctc_field_key_t
\S ctc_acl.h:ctc_acl_field_action_t
\S ctc_acl.h:ctc_acl_classify_udf_t
*/

#ifndef __CTC_ASW_ACL_H__
#define __CTC_ASW_ACL_H__
#ifdef __cplusplus
    extern "C" {
#endif

/***************************************************************************
*
* Header Files
*
****************************************************************************/
#include "ctc_acl.h"
/***************************************************************************
*
* Defines and Macros
*
****************************************************************************/

/***************************************************************************
*
* Data Structures
*
****************************************************************************/

/****************************************************************************
 *
* Function
*
*****************************************************************************/
/**
 @addtogroup acl ACL
 @{
*/

/**
 @brief     Init acl module.

 @param[in] lchip    local chip id

 @param[in] acl_global_cfg      Init parameter

 @remark[TMA]    Init acl module.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_init(uint8 lchip, ctc_acl_global_cfg_t* acl_global_cfg);

/**
 @brief De-Initialize acl module

 @param[in] lchip    local chip id

 @remark[TMA]  User can de-initialize the acl configuration

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_deinit(uint8 lchip);

/**
 @brief     Add an acl entry to a specified acl group.

 @param[in] lchip    local chip id

 @param[in] group_id      ACL group ID
 @param[in] acl_entry     ACL entry info.

 @remark[TMA]    Add an acl entry .
            The entry contains: entry_id and key_type refer to ctc_acl_entry_t.
            Remove an entry by using ctc_acl_remove_entry().
            It only add entry to the software table, install to hardware table
            by using ctc_acl_install_entry().
            PS. vlan edit is supported only for ingress acl.
            If acl entry is hash entry, you must install this entry immediately when you add a entry.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_add_entry(uint8 lchip,  uint32 group_id,  ctc_acl_entry_t* acl_entry);

/**
 @brief     Remove an acl entry.

 @param[in] lchip    local chip id

 @param[in] entry_id      entry id.

 @remark[TMA]    Remove an acl entry from software table,
            uninstall from hardware table by calling ctc_acl_uninstall_entry().

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_remove_entry(uint8 lchip, uint32 entry_id);


/**
 @brief     Add fields to key.

 @param[in] lchip    local chip id

 @param[in] entry_id      ACL entry id

 @param[in] p_field_list     Pointer to key field list.

 @param[in] p_field_cnt     Field number of key.

 @remark[TMA]    Add fields to key according to field type. If ERROR happened, p_field_cnt indicate successfully added field number of key for output.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_add_key_field_list(uint8 lchip, uint32 entry_id, ctc_field_key_t* p_field_list, uint32* p_field_cnt);

/**
 @brief     Add fields to action.

 @param[in] lchip    local chip id

 @param[in] entry_id      ACL entry id

 @param[in] p_field_list     Pointer to action field list.

 @param[in|out] p_field_cnt     Field number of action.

 @remark[TMA]    Add fields to action according to field type. If ERROR happened, p_field_cnt indicate successfully added field number of action for output.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_add_action_field_list(uint8 lchip, uint32 entry_id, ctc_acl_field_action_t* p_field_list, uint32* p_field_cnt);

/**
 @brief     Remove fields from action.

 @param[in] lchip    local chip id

 @param[in] entry_id      ACL entry id

 @param[in] p_field_list     Pointer to action field list.

 @param[in|out] p_field_cnt     Field number of action.

 @remark[TMA]    Remove fields from action according to field type. If ERROR happened, p_field_cnt indicate successfully added field number of action for output.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_remove_action_field_list(uint8 lchip, uint32 entry_id, ctc_acl_field_action_t* p_field_list, uint32* p_field_cnt);


/**
 @brief     Installs an entry into the hardware tables.

 @param[in] lchip    local chip id

 @param[in] entry_id      ACL entry ID

 @remark[TMA]    Installs an entry into the hardware tables.
            Must add an entry to software table first, by calling ctc_acl_add_entry().

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_install_entry(uint8 lchip, uint32 entry_id);

/**
 @brief     Uninstall an acl entry from the hardware tables.

 @param[in] lchip    local chip id

 @param[in] entry_id      ACL entry ID

 @remark[TMA]    Uninstall an acl entry from the hardware tables.
            The object of this entry is still in software table, thus can install again.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_uninstall_entry(uint8 lchip, uint32 entry_id);


/**
 @brief     Add udf entry.

 @param[in] lchip    local chip id

 @param[in] udf_entry      Pointer to ctc_acl_classify_udf_t struct.

 @remark[TMA]    add udf entry to hardware.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_add_udf_entry(uint8 lchip,  ctc_acl_classify_udf_t* udf_entry);

/**
 @brief     Remove udf entry.

 @param[in] lchip    local chip id

 @param[in] udf_entry      Pointer to ctc_acl_classify_udf_t struct.

 @remark[TMA]    remove udf entry from hardware.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_remove_udf_entry(uint8 lchip,  ctc_acl_classify_udf_t* udf_entry);

/**
 @brief     Add udf entry key field.

 @param[in] lchip    local chip id

 @param[in] udf_id    udf entry id

 @param[in] p_field_list   Pointer to ctc_field_key_t struct.

 @remark[TMA]    add udf entry key field to hardware.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_add_udf_entry_key_field(uint8 lchip, uint32 udf_id, ctc_field_key_t* key_field);

/**
 @brief     Add acl range info.

 @param[in] lchip    local chip id

 @param[in] range_info    Pointer to ctc_acl_range_t struct

 @param[in] index      hw index.

 @remark[TMA]    add acl range info to hardware.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_add_range_info(uint8 lchip, ctc_acl_range_t* range_info, uint8 index);

/**
 @brief     remove acl range info.

 @param[in] lchip    local chip id

 @param[in] index      hw index.

 @remark[TMA]    remove acl range info from hardware.

 @return CTC_E_XXX
*/
extern int32
ctc_asw_acl_remove_range_info(uint8 lchip, uint8 index);
#ifdef __cplusplus
}
#endif

#endif

